/**
 * 
 */
package edu.rice.images;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Scanner;

import edu.rice.myxo.utils.IOutils;

/**
 * @author frogy
 * 
 */
public class CoOccurrence {

	// Compute gray scale matrix, using level and offsets
	// Scale images using levels
	/*
	 * Now only work when no scale needed
	 */
	public static int[][] graycoMatrix(int[][] a, int level, int horoff,
			int veroff) {
		long timeStart = System.currentTimeMillis();

		int[] tmp = maxmin(a);
		int maxLevel = tmp[0];
		int minLevel = tmp[1];
		if (maxLevel - minLevel + 1 > level) {
			scale(a, level, maxLevel, minLevel);
		} else {
			level = maxLevel - minLevel + 1;
			zeromin(a, minLevel);
		}
		int[][] gcm = new int[level][level];
		for (int i = 0; i < gcm.length; i++) {
			gcm[i] = new int[level];
			for (int j = 0; j < gcm.length; j++) {
				gcm[i][j] = 0;
			}
		}
		for (int i = 0; i < a.length; i++) {
			for (int j = 0; j < a[0].length; j++) {
				int r = i + veroff;
				int c = j + horoff;
				if (r < 0 || r >= a.length || c < 0 || c >= a[0].length) {
					continue;
				} else {
					gcm[a[i][j]][a[r][c]] += 1;
				}
			}
		}

		long timeEnd = System.currentTimeMillis();
		System.out.println("Computing " + level + " by " + level
				+ " glcm using " + (timeEnd - timeStart) + "ms");
		return gcm;
	}

	public static int[] maxmin(int[][] a) {
		int[] maxmin = new int[2];
		maxmin[0] = 0;
		maxmin[1] = 1000;
		for (int i = 0; i < a.length; i++) {
			for (int j = 0; j < a[0].length; j++) {
				if (a[i][j] > maxmin[0]) {
					maxmin[0] = a[i][j];
				}
				if (a[i][j] < maxmin[1]) {
					maxmin[1] = a[i][j];
				}
			}
		}
		return maxmin;
	}

	public static void zeromin(int[][] a, int min) {
		for (int i = 0; i < a.length; i++) {
			for (int j = 0; j < a[0].length; j++) {
				a[i][j] -= min;
			}
		}
	}

	public static void scale(int[][] a, int level, int max, int min) {
		for (int i = 0; i < a.length; i++) {
			for (int j = 0; j < a[0].length; j++) {
				a[i][j] = (a[i][j] - min) * (level - 1) / (max - min);
			}
		}
	}

	public static int[][] readMatrix(String fn) {
		long timeStart = System.currentTimeMillis();
		File f = new File(fn);
		int[][] data = null;
		int nrow = 0;
		int ncol = 0;
		try {
			Scanner scline = new Scanner(f);
			ArrayList<ArrayList<Integer>> lr = new ArrayList<ArrayList<Integer>>();
			while (scline.hasNext()) {
				String line = scline.nextLine();
				Scanner scdata = new Scanner(line).useDelimiter(",");
				ArrayList<Integer> lc = new ArrayList<Integer>();
				while (scdata.hasNext()) {
					lc.add(scdata.nextInt());
					if (nrow == 0) {
						ncol++;
					}
				}
				if (lc.size() != ncol) {
					System.err.println("Must be a matrix!");
				}
				lr.add(lc);
				nrow++;
			}
			data = new int[nrow][ncol];
			for (int i = 0; i < nrow; i++) {
				for (int j = 0; j < ncol; j++) {
					data[i][j] = lr.get(i).get(j).intValue();
				}
			}
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		long timeEnd = System.currentTimeMillis();
		System.out.println("Reading " + nrow + " by " + ncol + " matrix using "
				+ (timeEnd - timeStart) + "ms");
		return data;
	}

	public static void main(String[] args) {
		IOutils iou = new IOutils();
		iou.writeMatrix(graycoMatrix(readMatrix("im.txt"), 256, 1, 0), ".",
				"glcm");
	}

}
